package com.itheima.service.Impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.common.domain.*;
import com.itheima.common.enums.ResponseCode;
import com.itheima.mapper.StockBlockRtInfoMapper;
import com.itheima.mapper.StockBusinessMapper;
import com.itheima.mapper.StockMarketIndexInfoMapper;
import com.itheima.mapper.StockRtInfoMapper;
import com.itheima.pojo.po.StockBlockRtInfo;
import com.itheima.pojo.po.StockBusiness;
import com.itheima.pojo.vo.PageResult;
import com.itheima.pojo.vo.R;
import com.itheima.service.StockService;
import com.itheima.utils.DateTimeUtil;
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeParser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import sun.text.CollatorUtilities;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class StockServiceImpl implements StockService {
    //    存放国内大盘的标记
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Autowired
    private StockBusinessMapper stockBusinessMapper;
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Override
    public List<StockBusiness> findAll() {
        List<StockBusiness> list = stockBusinessMapper.getAll();
        return list;
    }

    @Override
    public R<List<InnerMarketDomain>> innerIndexAll() {
        List<String> innerIds = stockInfoConfig.getInner();
//        获取最新有效交易日的时间
        Date lDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate();
//        模拟数据信息
        String mockDate = "20211226105600";

        lDate = DateTime.parse(mockDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        List<InnerMarketDomain> maps = stockMarketIndexInfoMapper.selectByIdsAndDate(innerIds, lDate);
        if (CollectionUtils.isEmpty(maps)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(maps);
    }

    @Override
    public R<List<StockBlockDomain>> sectorAllLimit() {
        //1.调用mapper接口获取数据 TODO 优化 避免全表查询 根据时间范围查询，提高查询效率
        List<StockBlockDomain> infos = stockBlockRtInfoMapper.sectorAllLimit();
        //2.组装数据
        if (CollectionUtils.isEmpty(infos)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(infos);

    }

    @Override
    public R<List<StockUpdownDomain>> stockIncreaseLimit() {
//        获取当前最近有效时间
        Date curTime = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate();
//        mock数据
        String mockStr = "2021-12-27 09:47:00";
        curTime = DateTime.parse(mockStr, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();

        List<StockUpdownDomain> list = stockRtInfoMapper.stockIncreaseLimit(curTime);

        if (list.isEmpty()) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        } else {
            return R.ok(list);
        }
    }

    @Override
    public R<PageResult<StockUpdownDomain>> StockPageSelect(Integer page, Integer pageSize) {

        PageHelper.startPage(page, pageSize);
        List<StockUpdownDomain> list = stockRtInfoMapper.stockAll();
        if (CollectionUtils.isEmpty(list)) {
            return R.error("暂无信息");
        }
        PageInfo<StockUpdownDomain> pageInfo = new PageInfo<>(list);

        PageResult<StockUpdownDomain> stockUpdownDomainPageResult = new PageResult<>(pageInfo);

        return R.ok(stockUpdownDomainPageResult);

    }

    @Override
    public R<Map> upAndDownSelect() {
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date curTime = curDateTime.toDate();
        Date openTime = DateTimeUtil.getOpenDate(curDateTime).toDate();
        String curTimeStr = "20220106142500";
        //对应开盘日期 mock_data
        String openTimeStr = "20220106092500";
        curTime = DateTime.parse(curTimeStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        openTime = DateTime.parse(openTimeStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        List<Map> upList = stockRtInfoMapper.upDownSelect(curTimeStr, openTimeStr, 1);
        List<Map> downList = stockRtInfoMapper.upDownSelect(curTimeStr, openTimeStr, 0);
        HashMap<Object, Object> infoMap = new HashMap<>();
        infoMap.put("upList", upList);
        infoMap.put("downList", downList);
        return R.ok(infoMap);
    }

    @Override
    public void stockExport(HttpServletResponse response, Integer page, Integer pageSize) {
//            1.设置响应数据的类型:excel
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
//        设置默认文件名称
            String fileName = URLEncoder.encode("stockRt", "UTF-8");
            response.setHeader("content-disposition", "attachment;fileName=" + fileName + ".xlsx");
            PageHelper.startPage(page, pageSize);
            List<StockUpdownDomain> infos = stockRtInfoMapper.stockAll();
            List<StockExcelDomain> excelDomains = infos.stream().map(info -> {
                StockExcelDomain domain = new StockExcelDomain();
                BeanUtils.copyProperties(info, domain);
                return domain;
            }).collect(Collectors.toList());
            EasyExcel.write(response.getOutputStream(), StockExcelDomain.class).
                    sheet("股票数据").doWrite(excelDomains);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    @Override
    public R<Map> stockTradeVol() {
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date curTime = curDateTime.toDate();
        DateTime openDateTime = DateTimeUtil.getOpenDate(curDateTime);
        Date openTime = openDateTime.toDate();
        String tDateStr = "20220103143000";
        curTime = DateTime.parse(tDateStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDateStr = "20220103093000";
        openTime = DateTime.parse(openDateStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        DateTime preDateTime = DateTimeUtil.getPreDateTime(curDateTime);
        Date preTime = preDateTime.toDate();
        DateTime preOpenDateTime = DateTimeUtil.getPreDateTime(openDateTime);
        Date preOpenTime = preOpenDateTime.toDate();
        String preTStr = "20220102143000";
        preTime = DateTime.parse(preTStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDateStr2 = "20220102093000";
        preOpenTime = DateTime.parse(openDateStr2, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        List<Map> tDate = stockMarketIndexInfoMapper.stockTradeVolCount(stockInfoConfig.getInner(), openTime, curTime);
        List<Map> preTDate = stockMarketIndexInfoMapper.stockTradeVolCount(stockInfoConfig.getInner(), preOpenTime, preTime);

        HashMap<Object, Object> h = new HashMap<>();
        h.put("volList", tDate);
        h.put("yesVolList", preTDate);
        return R.ok(h);
    }

    @Override
    public R<Map> stockUpDown() {
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date curTime = curDateTime.toDate();
        String mockDate = "20220106095500";
        curTime = DateTime.parse(mockDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        List<Map> infoMaps = stockRtInfoMapper.stockUpDownScope(curTime);
        List<String> upDownRange = stockInfoConfig.getUpDownRange();
        ArrayList<Map> orderList = new ArrayList<>();


        for (String key : upDownRange) {
            Map linShiMap = null;
            for (Map map : infoMaps) {
                if (key.equals(map.get("title"))) {

                    linShiMap = map;
                }
            }
            if (linShiMap != null) {
                orderList.add(linShiMap);
            } else {
                linShiMap = new HashMap<>();
                linShiMap.put("count", 0);
                linShiMap.put("title", key);
                orderList.add(linShiMap);
            }
        }


        HashMap<String, Object> data = new HashMap<>();
        data.put("time", curDateTime.toString("yyyy-MM-dd HH:mm:ss"));
        data.put("infos", orderList);
        return R.ok(data);


    }

    @Override
    public R<List<Stock4MinuteDomain>> stockScreenTimeSharing(String stockCode) {
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date curTime = curDateTime.toDate();
        Date pre20Days = curDateTime.minusDays(20).toDate();
        String avlDate = "20220106142500";
        curTime = DateTime.parse(avlDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        String openDate = "20220101093000";
        pre20Days = DateTime.parse(openDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        List<Stock4MinuteDomain> infos = stockRtInfoMapper.stockScreenTimeSharing(stockCode, pre20Days, curTime);
        return R.ok(infos);
    }

    @Override
    public R<List<Stock4EvrDayDomain>> stockScreenDkLine(String code) {
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date curTime = curDateTime.toDate();
        Date pre20Day = curDateTime.minusDays(20).toDate();
        String avlDate = "20220106142500";
        curTime = DateTime.parse(avlDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDate = "20220101093000";
        pre20Day = DateTime.parse(openDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        List<Stock4EvrDayDomain> infos = stockRtInfoMapper.stockScreenDkLine(code, pre20Day, curTime);
        return R.ok(infos);
    }
}
